/*  Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
    Gobbetti, Frank Slezak, ivanovlev, Kasha, Lem Dulfo, Pavel Elagin, Steffen
    Liebergeld

    This file is part of Gadgetbridge.

    Gadgetbridge is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Gadgetbridge is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
package org.likeapp.likeapp.activities;

import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import androidx.core.app.NavUtils;
import androidx.core.app.NotificationCompat;
import androidx.core.app.RemoteInput;
import androidx.core.content.FileProvider;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import org.likeapp.likeapp.impl.GBDevice;
import org.likeapp.likeapp.util.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Locale;
import java.util.Objects;

import org.likeapp.likeapp.GBApplication;
import org.likeapp.likeapp.R;
import org.likeapp.likeapp.model.ActivitySample;
import org.likeapp.likeapp.model.CallSpec;
import org.likeapp.likeapp.model.DeviceService;
import org.likeapp.likeapp.model.MusicSpec;
import org.likeapp.likeapp.model.MusicStateSpec;
import org.likeapp.likeapp.model.NotificationSpec;
import org.likeapp.likeapp.model.NotificationType;
import org.likeapp.likeapp.model.RecordedDataTypes;
import org.likeapp.likeapp.service.serial.GBDeviceProtocol;
import org.likeapp.likeapp.util.GB;

import static android.content.Intent.EXTRA_SUBJECT;
import static org.likeapp.likeapp.util.GB.NOTIFICATION_CHANNEL_ID;

public class DebugActivity extends AbstractGBActivity {
    private static final Logger LOG = LoggerFactory.getLogger(DebugActivity.class);

    private static final String EXTRA_REPLY = "reply";
    private static final String ACTION_REPLY = "org.likeapp.likeapp.DebugActivity.action.reply";

    public static final String ACTION_DEBUG = "org.likeapp.likeapp.DebugActivity.action.debug";
    public static final String EXTRA_LOG = "log";
    public static final String EXTRA_DISPLAY_SIZE = "display size";
    public static final String EXTRA_DISPLAY_DATA = "display data";
    public static final String EXTRA_VERSION = "version";
    public static final String EXTRA_VALUE = "value";

    public static final String PREF_LOG_AUTO = "log auto";

    private Bitmap displayBitmap;
    private int displayBitPerPixel = 1;

    private final static int[] colors4BitsPerPixel = new int []
    {
        0xff000000,
        0xffff0000,
        0xff00ff00,
        0xffffff00,
        0xff0000ff,
        0xffff00ff,
        0xff00ffff,
        0xffffffff,

        0xff000000,
        0xffff0000,
        0xff00ff00,
        0xffffff00,
        0xff0000ff,
        0xffff00ff,
        0xff00ffff,
        0xffffffff,
    };

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            switch (Objects.requireNonNull(intent.getAction())) {
                case ACTION_REPLY: {
                    Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
                    CharSequence reply = remoteInput.getCharSequence(EXTRA_REPLY);
                    LOG.info("got wearable reply: " + reply);
                    GB.toast(context, "got wearable reply: " + reply, Toast.LENGTH_SHORT, GB.INFO);
                    break;
                }
                case DeviceService.ACTION_REALTIME_SAMPLES:
                    handleRealtimeSample(intent.getSerializableExtra(DeviceService.EXTRA_REALTIME_SAMPLE));
                    break;
                case ACTION_DEBUG:
                    setDebugInfo (intent);
                    break;
                default:
                    LOG.info("ignoring intent action " + intent.getAction());
                    break;
            }
        }
    };

    private void setDebugInfo (Intent intent)
    {
        String log = intent.getStringExtra (EXTRA_LOG);

        if (debugBluetoothEvent.isChecked ())
        {
            byte[] value = intent.getByteArrayExtra (EXTRA_VALUE);
            if (value != null)
            {
                StringBuilder sb = new StringBuilder ();
                sb.append ("BT ");
                int v = value [0] & 0xff;
                if (v < 0x10)
                {
                    sb.append ('0');
                }
                sb.append (Integer.toHexString (v));
                sb.append (" [");
                sb.append (value.length);
                sb.append ("]:");

                for (int i = 1; i < value.length; i++)
                {
                    sb.append (' ');
                    int v1 = value [i] & 0xff;
                    if (v1 < 0x10)
                    {
                        sb.append ('0');
                    }
                    sb.append (Integer.toHexString (v1));
                }

                sb.append ('\n');

                String s = sb.toString ();
                logView.append (s);
                LOG.debug (s);
            }
        }

        if (log != null)
        {
            logView.append (log);
        }

        byte[] displaySize = intent.getByteArrayExtra (EXTRA_DISPLAY_SIZE);
        if (displaySize != null)
        {
            // Получить количество бит на пиксел
            displayBitPerPixel = displaySize [1];

            // Получить ширину экрана устройства
            int width  = (displaySize [2] & 0xff) | ((displaySize [3] & 0xff) << 8);

            // Получить высоту экрана устройства
            int height = (displaySize [4] & 0xff) | ((displaySize [5] & 0xff) << 8);

            if (displayView.getWidth () != width || displayView.getHeight () != height)
            {
                LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) displayView.getLayoutParams ();
                params.width = width;
                params.height = height;
                displayView.setLayoutParams (params);

                displayBitmap = Bitmap.createBitmap (width, height, Bitmap.Config.ARGB_8888);
            }
        }

        byte[] display = intent.getByteArrayExtra (EXTRA_DISPLAY_DATA);
        if (display != null && displayBitmap != null)
        {
            int width = displayBitmap.getWidth ();
            int height = displayBitmap.getHeight ();

            int off = (display [2] & 0xff) | ((display [3] & 0xff) << 8);

            // Ширина экрана, байтах
            int w = (width * displayBitPerPixel / 8);

            int y = off / w;
            int x = (off - y * w) * 8 / displayBitPerPixel;

            for (int i = 4; i < display.length; i++)
            {
                // Если вышли за пределы экрана устройства
                if (y >= height)
                {
                    break;
                }

                int c = display [i];

                // Цветовая схема "4 бита на пиксель"
                if (displayBitPerPixel == 4)
                {
                    displayBitmap.setPixel (x++, y, colors4BitsPerPixel[c & 0xf]);
                    if (x >= width)
                    {
                        x = 0;
                        y++;
                    }

                    displayBitmap.setPixel (x++, y, colors4BitsPerPixel[(c >> 4) & 0xf]);
                    if (x >= width)
                    {
                        x = 0;
                        y++;
                    }
                }
            }

            displayView.setImageBitmap (displayBitmap);
        }

        byte[] version = intent.getByteArrayExtra (EXTRA_VERSION);
        int start = 5;
        if (version != null && version.length > start)
        {
            int i;
            for (i = start; i < version.length; i++)
            {
                if (version [i] == 0)
                {
                    break;
                }
            }

            String text = String.format (Locale.getDefault (),"%s v.%d.%d.%d.%d",
              new String (version, start, i - start), version [1] & 0xff, version [2] & 0xff, version [3] & 0xff, version [4] & 0xff);

            boolean b = setVersion (R.id.debugVersion1, text) || setVersion (R.id.debugVersion2, text) || setVersion (R.id.debugVersion3, text) || setVersion (R.id.debugVersion4, text);
        }
    }

    private boolean setVersion (int id, String text)
    {
        TextView v = findViewById (id);
        boolean b = v.getText () == null || v.getText ().length () == 0;

        if (b)
        {
            v.setText (text);
        }

        return b;
    }

    private Spinner sendTypeSpinner;
    private EditText editContent;
    private TextView logView;
    private ImageView displayView;
    private CheckBox debugBluetoothEvent;

    private void handleRealtimeSample(Serializable extra) {
        if (extra instanceof ActivitySample) {
            ActivitySample sample = (ActivitySample) extra;
            GB.toast(this, "Heart Rate measured: " + sample.getHeartRate(), Toast.LENGTH_LONG, GB.INFO);
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_debug);

        logView = findViewById (R.id.logView);

        // Включить автоматическую прокрутку в окне отладочных сообщений
        logView.setMovementMethod (new ScrollingMovementMethod ());

        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_REPLY);
        filter.addAction(ACTION_DEBUG);
        filter.addAction(DeviceService.ACTION_REALTIME_SAMPLES);
        LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filter);
        registerReceiver(mReceiver, filter); // for ACTION_REPLY

        editContent = findViewById(R.id.editContent);

        ArrayList<String> spinnerArray = new ArrayList<>();
        for (NotificationType notificationType : NotificationType.values()) {
            spinnerArray.add(notificationType.name());
        }
        ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, spinnerArray);
        sendTypeSpinner = findViewById(R.id.sendTypeSpinner);
        sendTypeSpinner.setAdapter(spinnerArrayAdapter);

        Button sendButton = findViewById(R.id.sendButton);
        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                NotificationSpec notificationSpec = new NotificationSpec();
                String testString = editContent.getText().toString();
                notificationSpec.phoneNumber = testString;
                notificationSpec.body = testString;
                notificationSpec.sender = testString;
                notificationSpec.subject = testString;
                notificationSpec.type = NotificationType.values()[sendTypeSpinner.getSelectedItemPosition()];
                notificationSpec.pebbleColor = notificationSpec.type.color;
                GBApplication.deviceService().onNotification(notificationSpec);
            }
        });

        Button incomingCallButton = findViewById(R.id.incomingCallButton);
        incomingCallButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                CallSpec callSpec = new CallSpec();
                callSpec.command = CallSpec.CALL_INCOMING;
                callSpec.number = editContent.getText().toString();
                GBApplication.deviceService().onSetCallState(callSpec);
            }
        });
        Button outgoingCallButton = findViewById(R.id.outgoingCallButton);
        outgoingCallButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                CallSpec callSpec = new CallSpec();
                callSpec.command = CallSpec.CALL_OUTGOING;
                callSpec.number = editContent.getText().toString();
                GBApplication.deviceService().onSetCallState(callSpec);
            }
        });

        Button startCallButton = findViewById(R.id.startCallButton);
        startCallButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                CallSpec callSpec = new CallSpec();
                callSpec.command = CallSpec.CALL_START;
                GBApplication.deviceService().onSetCallState(callSpec);
            }
        });
        Button endCallButton = findViewById(R.id.endCallButton);
        endCallButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                CallSpec callSpec = new CallSpec();
                callSpec.command = CallSpec.CALL_END;
                GBApplication.deviceService().onSetCallState(callSpec);
            }
        });

        Button rebootButton = findViewById(R.id.rebootButton);
        rebootButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                GBApplication.deviceService().onReset(GBDeviceProtocol.RESET_FLAGS_REBOOT);
            }
        });

        Button factoryResetButton = findViewById(R.id.factoryResetButton);
        factoryResetButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new AlertDialog.Builder(DebugActivity.this)
                        .setCancelable(true)
                        .setTitle(R.string.debugactivity_really_factoryreset_title)
                        .setMessage(R.string.debugactivity_really_factoryreset)
                        .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                GBApplication.deviceService().onReset(GBDeviceProtocol.RESET_FLAGS_FACTORY_RESET);
                            }
                        })
                        .setNegativeButton(R.string.Cancel, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                            }
                        })
                        .show();
            }
        });

        Button heartRateButton = findViewById(R.id.HeartRateButton);
        heartRateButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                GB.toast("Measuring heart rate, please wait...", Toast.LENGTH_LONG, GB.INFO);
                GBApplication.deviceService().onHeartRateTest();
            }
        });

        Button setFetchTimeButton = findViewById(R.id.SetFetchTimeButton);
        setFetchTimeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                final Calendar currentDate = Calendar.getInstance();
                Context context = getApplicationContext();

                if (context instanceof GBApplication) {
                    GBApplication gbApp = (GBApplication) context;
                    final GBDevice device = gbApp.getDeviceManager().getSelectedDevice();
                    if (device != null) {
                        new DatePickerDialog(DebugActivity.this, new DatePickerDialog.OnDateSetListener() {
                            @Override
                            public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
                                Calendar date = Calendar.getInstance();
                                date.set(year, monthOfYear, dayOfMonth);

                                long timestamp = date.getTimeInMillis() - 1000;
                                GB.toast("Setting lastSyncTimeMillis: " + timestamp, Toast.LENGTH_LONG, GB.INFO);

                                SharedPreferences.Editor editor = GBApplication.getDeviceSpecificSharedPrefs(device.getAddress()).edit();
                                editor.remove("lastSyncTimeMillis"); //FIXME: key reconstruction is BAD
                                editor.putLong("lastSyncTimeMillis", timestamp);
                                editor.apply();
                            }
                        }, currentDate.get(Calendar.YEAR), currentDate.get(Calendar.MONTH), currentDate.get(Calendar.DATE)).show();
                    } else {
                        GB.toast("Device not selected/connected", Toast.LENGTH_LONG, GB.INFO);
                    }
                }


            }
        });


        Button setMusicInfoButton = findViewById(R.id.setMusicInfoButton);
        setMusicInfoButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MusicSpec musicSpec = new MusicSpec();
                String testString = editContent.getText().toString();
                musicSpec.artist = testString + "(artist)";
                musicSpec.album = testString + "(album)";
                musicSpec.track = testString + "(track)";
                musicSpec.duration = 10;
                musicSpec.trackCount = 5;
                musicSpec.trackNr = 2;

                GBApplication.deviceService().onSetMusicInfo(musicSpec);

                MusicStateSpec stateSpec = new MusicStateSpec();
                stateSpec.position = 0;
                stateSpec.state = 0x01; // playing
                stateSpec.playRate = 100;
                stateSpec.repeat = 1;
                stateSpec.shuffle = 1;

                GBApplication.deviceService().onSetMusicState(stateSpec);
            }
        });

        Button setTimeButton = findViewById(R.id.setTimeButton);
        setTimeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                GBApplication.deviceService().onSetTime();
            }
        });

        Button testNotificationButton = findViewById(R.id.testNotificationButton);
        testNotificationButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                testNotification();
            }
        });

        Button testPebbleKitNotificationButton = findViewById(R.id.testPebbleKitNotificationButton);
        testPebbleKitNotificationButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                testPebbleKitNotification();
            }
        });

        final Button fetchDebugLogsButton = findViewById(R.id.fetchDebugLogsButton);
        fetchDebugLogsButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                GBApplication.deviceService().onFetchRecordedData(RecordedDataTypes.TYPE_DEBUGLOGS);
            }
        });

        Button testNewFunctionalityButton = findViewById(R.id.testNewFunctionality);
        testNewFunctionalityButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                testNewFunctionality();
            }
        });

        Button shareLogButton = findViewById(R.id.shareLog);
        shareLogButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showWarning();
            }
        });

        Button clearLogButton = findViewById (R.id.clearLog);
        clearLogButton.setOnClickListener (new View.OnClickListener ()
        {
            @Override
            public void onClick (View v)
            {
                logView.setText ("");
            }
        });

        debugBluetoothEvent = findViewById (R.id.debugBluetoothEvent);

        CheckBox debugLogAuto = findViewById (R.id.debugLogAuto);
        debugLogAuto.setOnCheckedChangeListener (new CompoundButton.OnCheckedChangeListener ()
        {
            @Override
            public void onCheckedChanged (CompoundButton buttonView, boolean isChecked)
            {
                // Установить признак автоматического чтения log-файла
                setLogAuto (isChecked);

                if (isChecked)
                {
                    fetchDebugLogsButton.callOnClick ();
                }
            }
        });

        debugLogAuto.setChecked (getLogAuto ());

        displayView = findViewById (R.id.display);
        displayView.setOnClickListener (new View.OnClickListener ()
        {
            @Override
            public void onClick (View v)
            {
                if (displayBitmap != null)
                {
                    try
                    {
                        File outputDir = new File (FileUtils.getExternalFilesDir ().getAbsolutePath ());
                        File outputFile = File.createTempFile ("temp_display", ".png", outputDir);
                        try (FileOutputStream fileOutputStream = new FileOutputStream (outputFile))
                        {
                            displayBitmap.compress (Bitmap.CompressFormat.PNG, 100, fileOutputStream);
                        }

                        Intent shareIntent = new Intent ();
                        shareIntent.setFlags (Intent.FLAG_GRANT_READ_URI_PERMISSION);
                        shareIntent.setAction (Intent.ACTION_SEND);
                        Uri outputUri = FileProvider.getUriForFile (DebugActivity.this, getApplicationContext ().getPackageName () + ".screenshot_provider", outputFile);
                        shareIntent.putExtra (Intent.EXTRA_STREAM, outputUri);
                        shareIntent.setDataAndType (outputUri, "image/png");
                        startActivity (Intent.createChooser (shareIntent, getResources ().getText (R.string.send_via)));
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace ();
                    }
                }
            }
        });
    }

    private void showWarning() {
        new AlertDialog.Builder(this)
                .setCancelable(true)
                .setTitle(R.string.warning)
                .setMessage(R.string.share_log_warning)
                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        shareLog();
                    }
                })
                .setNegativeButton(R.string.Cancel, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // do nothing
                    }
                })
                .show();
    }

    private void testNewFunctionality() {
        GBApplication.deviceService().onTestNewFunction();
    }

    private void shareLog() {
        String fileName = GBApplication.getLogPath();
        if (fileName != null && fileName.length() > 0) {
            File logFile = new File(fileName);
            if (!logFile.exists()) {
                GB.toast("File does not exist", Toast.LENGTH_LONG, GB.INFO);
                return;
            }

            Uri uri = FileProvider.getUriForFile (this, getApplicationContext ().getPackageName () + ".screenshot_provider", logFile);

            Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
            emailIntent.setType("*/*");
            emailIntent.putExtra(EXTRA_SUBJECT, "LikeApp log file");
            emailIntent.putExtra(Intent.EXTRA_STREAM, uri);
            startActivity(Intent.createChooser(emailIntent, "Share File"));
        }
    }

    private void testNotification() {
        Intent notificationIntent = new Intent(getApplicationContext(), DebugActivity.class);
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0,
                notificationIntent, 0);

        NotificationManager nManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_REPLY)
                .build();

        Intent replyIntent = new Intent(ACTION_REPLY);

        PendingIntent replyPendingIntent = PendingIntent.getBroadcast(this, 0, replyIntent, 0);

        NotificationCompat.Action action =
                new NotificationCompat.Action.Builder(android.R.drawable.ic_input_add, "Reply", replyPendingIntent)
                        .addRemoteInput(remoteInput)
                        .build();

        NotificationCompat.WearableExtender wearableExtender = new NotificationCompat.WearableExtender().addAction(action);

        NotificationCompat.Builder ncomp = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
                .setContentTitle(getString(R.string.test_notification))
                .setContentText(getString(R.string.this_is_a_test_notification_from_gadgetbridge))
                .setTicker(getString(R.string.this_is_a_test_notification_from_gadgetbridge))
                .setSmallIcon(R.drawable.ic_notification)
                .setAutoCancel(true)
                .setContentIntent(pendingIntent)
                .extend(wearableExtender);

        if (nManager != null) {
            nManager.notify((int) System.currentTimeMillis(), ncomp.build());
        }
    }

    private void testPebbleKitNotification() {
        Intent pebbleKitIntent = new Intent("com.getpebble.action.SEND_NOTIFICATION");
        pebbleKitIntent.putExtra("messageType", "PEBBLE_ALERT");
        pebbleKitIntent.putExtra("notificationData", "[{\"title\":\"PebbleKitTest\",\"body\":\"sent from Gadgetbridge\"}]");
        getApplicationContext().sendBroadcast(pebbleKitIntent);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                NavUtils.navigateUpFromSameTask(this);
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
        unregisterReceiver(mReceiver);

        // Сбросить признак автоматического чтения log-файла
        setLogAuto (false);
    }

    public static boolean getLogAuto ()
    {
        return GBApplication.getContext ().getSharedPreferences ("DebugActivity", MODE_PRIVATE).getBoolean (PREF_LOG_AUTO, false);
    }

    public void setLogAuto (boolean enabled)
    {
        GBApplication.getContext ().getSharedPreferences ("DebugActivity", MODE_PRIVATE).edit ().putBoolean (PREF_LOG_AUTO, enabled).apply ();
    }
}
